//#########################################################################
//                              WackiEngie
//           Copyright (c) 2014 Marc Wacker. All rights reserved.
//#########################################################################

#pragma once

#include "WeCorePrerequisites.h"
#include "WeModule.h"
#include "WeEvent.h"
#include "WeInputEvents.h"

namespace WackiEngine
{
	
	class Platform : public Module<Platform>
	{
	public:
		Event<void(const PointerEvent&)>	mouseMove;
		Event<void(const PointerEvent&)>	mouseDown;
		Event<void(const PointerEvent&)>	mouseUp;
		Event<void(const PointerEvent&)>	mouseDoubleClick;
		Event<void(const PointerEvent&)>	mouseWheel;

		// keyboard key signals
		// TODO: test if glfw sends out multiple key callbacks per frame
		Event<void(KeyCode)>				keyboardDown;
		Event<void(KeyCode)>				keyboardUp;

		Event<void(uint32)>					charInput;

		Event<void()>						mouseWindowLeave;
		Event<void()>						mouseWindowEnter;

		Event<void(int32, int32)>			resize;
		Event<void()>						windowFocusReceived;
		Event<void()>						windowFocusLost;
		Event<void()>						windowClosed;


		Platform(int32 width, int32 height, const String& title);
		~Platform();

		// get the OS msgs and fire events that happend
		void update();

		void setTitle(const String& title);

		// callbacks for the GLFW events
		void onMouseMove(float x, float y);
		void onMouseDown(int32 button);
		void onMouseUp(int32 button);
		void onMouseWheel(float x, float y);

		void onKeyboardDown(KeyCode key);
		void onKeyboardUp(KeyCode key);

		void onCharInput(uint32 character);

		void onResize(int32 w, int32 h);
		void onMouseWindowEnter();
		void onMouseWindowLeave();
		void onWindowClosed();



		// for now we handle window stuff here too, so we swap buffers on the main window with this call
		// in the future this should be handled by a window class and the platform class shouldnt care about it...
		void swapBuffers();

	private:
		float	_mouseX;
		float	_mouseY;
		Map<KeyCode, double> _lastMouseDown;
		int32	_modifiers;
		int32	_width;
		int32	_height;
	};

	Platform& gPlatform();

}